<!-- Ref全家桶 -->
<template>
    <div class="conten">
        Ref: {{  txt  }}
    </div>
    <div class="conten">
        shallowRef: {{  txt2  }}
    </div>
    <div class="conten">
        customRef: {{ txt3 }}
    </div>
    <button @click="clickFun">修改</button>
</template>

<script setup lang="ts">
    import { ref, reactive, onMounted, Ref, isRef, shallowRef, triggerRef, customRef } from "vue";

    type txtType = {
        name?: string
    }
    const txt: Ref<txtType> = ref({
        name: 'body'
    })
    // 判断是否是Ref对象
    // console.log(isRef(txt));  

    const clickFun = () => {
        // txt.value.name = txt.value.name == 'body' ? 'head' : 'body';

        // shallowRef这是不会修改的，并且不能和Ref混合写，会造成shallowRef视图更新（因为Ref已经调用过triggerRef）
        // txt2.value.name = txt2.value.name == 'body' ? 'head' : 'body';  
        // // 正常使用shallowRef
        // // txt2.value = { name: '5555' }
        // console.log(txt2);
        // // triggerRef 强制触发依赖于一个shallowRef的副作用，强制更新依赖的值
        // triggerRef(txt2)


        txt3.value = 'customRef 修改了';
    }

    // ref 深层次响应式  shallowRef浅层响应式
    const txt2 = shallowRef({ name: 'body' })

    // customRef 创建一个自定义的 ref，显式声明对其依赖追踪和更新触发的控制方式
    function MyRef<T>(value: T){
        // 防抖
        let timer: any;
        // track:收集依赖  trigger:触发依赖
        return customRef((track, trigger)=>{
            return {
                get() {
                    track();
                    return value;
                }, 
                set(newValue) {
                    
                    clearTimeout(timer);
                    timer = setTimeout(()=>{
                        console.log('触发了');
                        value = newValue;
                        timer = null;
                        trigger();
                    }, 500)
                }
            }
        })
    }
    const txt3 = MyRef<string>('老虎');
    console.log(txt.value);
    

    onMounted(()=>{  })
</script>
<style scoped lang="less">
</style>